package com.inspinia.upms.rpc.service;

import com.beust.jcommander.internal.Lists;
import com.google.common.base.Joiner;
import com.hazelcast.util.MD5Util;
import com.inspinia.base.common.exception.BusinessException;
import com.inspinia.base.dao.BaseDao;
import com.inspinia.base.pagination.Pager;
import com.inspinia.base.service.BaseServiceImpl;
import com.inspinia.base.util.CollectionUtil;
import com.inspinia.base.util.SecurityUtil;
import com.inspinia.base.util.ValidateUtil;
import com.inspinia.upms.common.model.UserConstants;
import com.inspinia.upms.common.model.org.UpmsOrganization;
import com.inspinia.upms.common.model.user.UpmsUser;
import com.inspinia.upms.common.model.user.UpmsUserVo;
import com.inspinia.upms.dao.UpmsUserDao;
import com.inspinia.upms.rpc.api.*;
import net.sf.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.ValidationException;
import java.util.*;

/**
 * 用户 业务层处理
 * 
 * @author veblen
 */
@Service
public class UpmsUserServiceImpl extends BaseServiceImpl<UpmsUser> implements UpmsUserService {

    @Resource
    private UpmsUserDao userDao;
    @Resource
    private UpmsRoleService roleService;
    @Resource
    private UpmsResourceService resourceService;
    @Resource
    private UpmsOrganizationService organizationService;
    @Resource
    private UpmsDeptService departmentService;
    @Resource
    private UpmsPostService postService;

    @Override
    protected BaseDao<UpmsUser> getDao() {
        return userDao;
    }

    /**
     * 插入用户到数据库
     * @param bean
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(UpmsUser bean) {
        validate(bean, true);
        return super.insert(bean);
    }

    /**
     * 对用户实体进行验证
     *
     * @param bean     用户
     * @param isCreate true表示创建时的验证
     */
    private void validate(UpmsUser bean, boolean isCreate) {
        if (isCreate) {
            boolean b = validPhone(bean.getPhone());
            if (b) {
                throw new ValidationException("手机号码已存在");
            }
        }
    }
    /**
     * 根据用户id获取角色id
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<Long> findRoleIds(Long userId) {
        return userDao.findRoleIdByUserId(userId);
    }

    @Override
    public List<Long> findDeptIds(Long userId) {
        return userDao.findDeptIdsByUseId(userId);
    }

    @Override
    public List<Long> findOrgIds(Long userId) {
        List<Long> deptIds = findDeptIds(userId);
        if (CollectionUtil.isNotEmpty(deptIds)) {
            return organizationService.findOrgIdByDeptIds(deptIds);
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<UpmsUser> findUserByRoleNameAndOrgId(Long orgId, String roleName) {
        return userDao.findUserByRoleNameAndOrgId(orgId, roleName);
    }

    /**
     * 查找用户所在的部门的名称
     *
     * @param userId 用户id
     * @return 用户所在部门名称集合
     */
    @Override
    public List<String> findDeptNames(Long userId) {
        return departmentService.findNamesByUserId(userId);
    }

    /**
     * 检查电话是否重复
     * @param phone
     * @return
     */

    @Override
    public boolean validPhone(String phone) {
        if (ValidateUtil.isMobile(phone)) {
            return userDao.countByPhone(phone) > 0;
        }
        return false;
    }

    /**
     * 检查email是否重复
     * @param email
     * @return
     */

    @Override
    public boolean validEmail(String email) {
        if (ValidateUtil.isEmail(email)) {
            return userDao.countByEmail(email) > 0;
        }
        return false;
    }

    /**
     * 获取所有用户信息
     * @return
     */
    @Override
    public List<UpmsUser> getUserList() {
        return userDao.getUserList();
    }

    /**
     * 根据用户id获取角色id
     * @param userId 用户id
     * @return
     */
    @Override
    public List<Long> getRoleIds(Long userId) {
        return userDao.findRoleIdByUserId(userId);
    }


    /**
     * 向中间表sys_user_role插入数据
     * @param roleIds 角色id
     * @param userId 用户id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int setRole(Long[] roleIds, Long userId) {
        if (roleIds == null) {
            if (userId != 1) {
                return userDao.deleteRole(userId);
            }else {
                return userDao.deleteRoleAdmin();
            }
        } else {
            int i = 0;
            if (userId != 1) {
                userDao.deleteRole(userId);
                i = userDao.addRole(userId, Arrays.asList(roleIds));
            } else {
                userDao.deleteRoleAdmin();
                i = userDao.addRole(userId, Arrays.asList(roleIds));
            }

            return i;
        }
    }

    @Override
    public Pager<UpmsUserVo> findPage(UpmsUserVo userVo) {
        if (userVo.getOrgId() != null) {

            //查找机构的人员id集合
            List<Long> userIds = findUserIdsByOrgId(userVo.getOrgId());

            //如果没有用户,那么直接返回无数据
            if (CollectionUtil.isEmpty(userIds)) {
                return new Pager<>();
            }
            userVo.setUserIds(userIds);

        }

        if (userVo.getDeptIds() != null) {

            //查找部门的人员id集合
            List<Long> userIds = findUserIdsByDeptId(userVo.getDeptId());
            //如果没有用户,那么直接返回无数据
            if (CollectionUtil.isEmpty(userIds)) {
                return new Pager<>();
            }
            Iterator<Long> iterator = userIds.iterator();
            while (iterator.hasNext()) {
                Long next = iterator.next();
                if (next == null) {
                    iterator.remove();
                }

            }
            userVo.setUserIds(userIds);
        }

        if (userVo.getPostId() != null) {

            //查找岗位的人员id集合
            List<Long> userIds = findPostIds(userVo.getDeptId());
            //如果没有用户,那么直接返回无数据
            if (CollectionUtil.isEmpty(userIds)) {
                return new Pager<>();
            }
            userVo.setUserIds(userIds);
        }
        Pager page = userDao.findPage(userVo);

        //组装人员的部门名称
        List<UpmsUserVo> userVos = new ArrayList<>(page.getPageSize());
        for (UpmsUser user : (List<UpmsUser>) page.getList()) {
            UpmsUserVo vo = new UpmsUserVo();
            BeanCopier.create(UpmsUser.class, UpmsUserVo.class, false).copy(user, vo, null);
            String deptName = findDeptNamesByUserId(user.getUserId());
            vo.setDeptName(deptName);
            String postName = findPostName(user.getUserId());
            vo.setPostName(postName);
            String roleName = findRoleName(user.getUserId());
            vo.setRoleName(roleName);
            userVos.add(vo);

        }
        page.setList(userVos);
        return page;
    }

    /**
     * 获取用户的角色名称
     *
     * @param userId 用户id
     * @return
     */
    private String findRoleName(Long userId) {
        List<String> roleNames = roleService.findRoleNamesByUserId(userId);
        return Joiner.on(",").join(roleNames);
    }

    /**
     * 获取用户的岗位名称
     *
     * @param userId
     * @return
     */
    private String findPostName(Long userId) {
        List<Long> postIds = findPostIds(userId);
        List<String> postNames = postService.findNamesByIds(postIds);
        return CollectionUtil.list2string(postNames);
    }

    @Override
    public List<Long> findPostIds(Long userId) {
        return userDao.findPostIds(userId);
    }
    /**
     * 根据用户id获取用户所有部门的名称
     *
     * @param id 用户id
     * @return
     */
    private String findDeptNamesByUserId(Long id) {
        List<String> deptNames = departmentService.findNamesByUserId(id);
        return CollectionUtil.list2string(deptNames);
    }

    /**
     * 查找部门的所有人员id
     *
     * @param deptId
     * @return
     */
    @Override
    public List<Long> findUserIdsByDeptId(Long deptId) {
        return userDao.findUserIdsByDeptIds(Lists.newArrayList(deptId));
    }

    @Override
    public List<Long> findUserIdsByDeptIds(Collection<Long> deptIds) {
        if (CollectionUtil.isNotEmpty(deptIds)) {
            return userDao.findUserIdsByDeptIds(deptIds);
        }
        return new ArrayList<>(0);
    }

    /**
     * 查找机构下所有用户的id
     *
     * @param orgId 机构id
     * @return 用户id集合
     */
    public List<Long> findUserIdsByOrgId(Long orgId) {
        //找到机构的所有子机构
        List<Long> orgIds = new ArrayList<>();
        organizationService.findChildrenById(orgId, orgIds);
        orgIds.add(orgId);

        //根据机构找到机构的部门。
        List<Long> deptIds = departmentService.findDeptIdsByOrgIds(orgIds);

        if (!deptIds.isEmpty()) {

            //查找机构的人员id集合
            return userDao.findUserIdsByDeptIds(deptIds);
        }
        return new ArrayList<>(0);
    }


    /**
     * MD5加密
     * @param sourceStr
     * @return
     */
    @Override
    public String md5(String sourceStr) {
        return MD5Util.toMD5String(sourceStr);
    }

    @Override
    public UpmsUserVo getVo(Long userId) {
        return user2vo(get(userId));
    }

    @Override
    public UpmsUserVo user2vo(UpmsUser user) {
        UpmsUserVo vo = new UpmsUserVo();
        BeanCopier.create(UpmsUser.class, UpmsUserVo.class, false).copy(user, vo, null);
        List<String> deptNames = departmentService.findNamesByUserId(user.getUserId());
        List<String> roleNames = roleService.findRoleNamesByUserId(user.getUserId());
        vo.setRoleNames(roleNames);
        vo.setDeptNames(deptNames);
        vo.setDeptName(Joiner.on(",").join(deptNames));
        vo.setRoleName(Joiner.on(",").join(roleNames));
        List<Long> roleIds = findRoleIds(user.getUserId());
        if (CollectionUtil.isNotEmpty(roleIds)){
            vo.setRoleIds(roleIds.toArray(new Long[roleIds.size()]));
        }
        List<Long> deptIds = findDeptIds(user.getUserId());
        if (CollectionUtil.isNotEmpty(deptIds)){
            vo.setDeptIds(deptIds.toArray(new Long[deptIds.size()]));
        }
        List<Long> postIds = findPostIds(user.getUserId());
        if (CollectionUtil.isNotEmpty(postIds)){
            vo.setPostIds(postIds.toArray(new Long[postIds.size()]));
        }
        UpmsOrganization org = organizationService.findOrgByUserId(user.getUserId());
        if (org != null) {
            vo.setOrgId(org.getId());
            vo.setFirstCityId(org.getCityId());
            vo.setFirstProvinceId(org.getProvinceId());
            vo.setOrgName(org.getName());
        }
        vo.setUserId(user.getUserId());
        return vo;
    }


    @Override
    public List<UpmsUserVo> findVos(Collection userIds) {
        List<UpmsUser> users = findUserByIds(userIds);
        List<UpmsUserVo> vos = new ArrayList<>(userIds.size());
        for (UpmsUser user : users) {
            vos.add(user2vo(user));
        }
        return vos;
    }

    @Override
    public List<UpmsUser> findUserByIds(Collection userIds) {
        if (CollectionUtil.isNotEmpty(userIds)) {
            return userDao.findUserByIds(userIds);
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<Long> findAllUserIds() {
        return userDao.findAllUserIds();
    }

    @Override
    public String getRealNameById(Long userId) {
        return userDao.getRealNameById(userId);
    }
    @Override
    public List<Long> findOrgIdsByUserId(Long userId) {
        return userDao.findOrgIdsByUserId(userId);
    }

    @Override
    public List<Long> findResourceIdsByRoleAndPost(List<Long> roleIds, List<Long> postIds) {
        List<Long> roleResourceIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roleIds)) {
            roleResourceIds = resourceService.findResourceIdsByRoleIds(roleIds);
        }
        List<Long> resourceIdsByPostIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(postIds)) {
            resourceIdsByPostIds = resourceService.findResourceIdsByPostIds(postIds);
        }

        //去重
        List<Long> list = new ArrayList<>();
        list.addAll(roleResourceIds);
        list.addAll(resourceIdsByPostIds);
        CollectionUtil.removeDuplicate(list);

        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(UpmsUser user, List<Long> roleIds, List<Long> deptIds, List<Long> postIds) {
        //判断用户所选部门和所配的角色是否相符
        validUser(user);
        if (user.getPassword() == null) {
            user.setPassword(UserConstants.initPwd);
        } else {
            user.setPassword(SecurityUtil.encodePwd(user.getPassword()));
        }
        if (user.getRealName() == null) {
            user.setRealName(user.getUserName());
        }
        int insert = insert(user);
        if (insert > 0) {
            if (roleIds != null) {
                setRole(user.getUserId(), roleIds);
            }
            if (deptIds != null) {
                setDept(user.getUserId(), deptIds);
            }
            if (postIds != null) {
                setPost(user.getUserId(), postIds);
            }
        }
        return insert;
    }
    /**
     * 向中间表sys_user_role插入数据
     *
     * @param userId  用户id
     * @param roleIds 角色id
     * @return
     */
    private int setRole(Long userId, List<Long> roleIds) {
        userDao.deleteRole(userId);
        if (CollectionUtil.isNotEmpty(roleIds)) {
            return userDao.addRole(userId, roleIds);
        }
        return 0;
    }
    /**
     * 设置岗位
     *
     * @param id      用户id
     * @param postIds 岗位id集合
     * @return
     */
    private int setPost(Long id, List<Long> postIds) {
        userDao.deletePost(id);
        if (CollectionUtil.isNotEmpty(postIds)) {
            return userDao.addPost(id, postIds);
        }
        return 0;
    }

    private void validUser(UpmsUser user) {
        boolean b = validUsername(user.getUserName(), user.getUserId());
        if (!b) {
            throw new BusinessException("用户名已存在");
        }
    }

    /**
     * 为用户添加部门
     *
     * @param userId  橘色id
     * @param deptIds 部门id
     * @return
     */
    private int setDept(Long userId, List<Long> deptIds) {
        userDao.deleteDept(userId);
        if (CollectionUtil.isNotEmpty(deptIds)) {
            return userDao.addDept(userId, deptIds);
        }
        return 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int update(UpmsUser user, List<Long> roleIds, List<Long> deptIds, List<Long> postIds) {
        //validRoleAndDept(deptIds,OrganizationMapperConfig.WARNING_SEND_ROLE);
        validUser(user);
        if (user.getRealName() == null) {
            user.setRealName(user.getUserName());
        }
        int update = update(user);
        if (update > 0) {
            setRole(user.getUserId(), roleIds);
            setDept(user.getUserId(), deptIds);
            setPost(user.getUserId(), postIds);
        }
        return update;
    }

    @Override
    public boolean validUsername(String username, Long id) {
        return userDao.countByUsername(username, id) == 0;
    }

    @Override
    public int delete(Long userId){
        //用户角色
        userDao.deleteRole(userId);
        //用户部门
        userDao.deleteDept(userId);
        //用户岗位
        userDao.deletePost(userId);
        //用户
        return super.delete(userId);
    }
}
